#!/usr/bin/env python
# coding=utf-8

import json
import traceback
import functools
import urlparse
import urllib
import utils
import tornado.web
from tornado.options import options
from mako.template import Template


def authenticated(method):
    """Decorate methods with this to require that the user be logged in."""

    @functools.wraps(method)
    def wrapper(self, *args, **kwargs):
        if not self.current_user:
            if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest': # jQuery 等库会附带这个头
                self.set_header('Content-Type', 'application/json; charset=UTF-8')
                self.write(json.dumps({'code': 1, 'msg': u'您的会话已过期，请重新登录！'}))
                return
            if self.request.method in ("GET", "POST", "HEAD"):
                url = self.get_login_url()
                if "?" not in url:
                    if urlparse.urlsplit(url).scheme:
                        # if login url is absolute, make next absolute too
                        next_url = self.request.full_url()
                    else:
                        next_url = self.request.uri
                    url += "?" + urllib.urlencode(dict(next=next_url))
                self.redirect(url)
                return
            raise tornado.web.HTTPError(403)
        else:
            return method(self, *args, **kwargs)

    return wrapper


def route(url_pattern):
    def handler_wapper(cls):
        assert (issubclass(cls, BaseHandler))
        cls.url_pattern = url_pattern
        return cls

    return handler_wapper


class BaseHandler(tornado.web.RequestHandler):
    url_pattern = None

    def __init__(self, *argc, **argkw):
        super(BaseHandler, self).__init__(*argc, **argkw)
        self.logging = self.application.logging
        self.cache_key = "BaseHandler"

    def initialize(self):
        self.db = self.application.db

    def on_finish(self):
        pass


    def get_error_html(self, status_code=500, **kwargs):
        if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return self.render_json(code=1, msg=u"%s:服务器处理失败，请联系管理员" % status_code)

        if status_code == 404:
            return self.render_string("error.html", msg=u"页面不存在")
        elif status_code == 403:
            return self.render_string("error.html", msg=u"非法的请求")
        elif status_code == 500:
            if options.debug:
                return self.render_string("error.html", msg=traceback.format_exc())
            return self.render_string("error.html", msg=u"服务器处理失败，请联系管理员")
        else:
            return self.render_string("error.html", msg=u"%s:服务器处理失败，请联系管理员" % status_code)

    def render(self, template_name, **template_vars):
        html = self.render_string(template_name, **template_vars)
        self.write(html)


    def render_error(self, **template_vars):
        tpl = "error.html"
        html = self.render_string(tpl, **template_vars)
        self.write(html)

    def render_json(self, **template_vars):
        if not template_vars.has_key("code"):
            template_vars["code"] = 0
        resp = json.dumps(template_vars, ensure_ascii=False)
        self.write(resp)

    def render_string(self, template_name, **template_vars):
        template_vars["xsrf_form_html"] = self.xsrf_form_html
        template_vars["current_user"] = self.current_user
        template_vars["request"] = self.request
        template_vars["handler"] = self
        template_vars["utils"] = utils
        mytemplate = self.application.tp_lookup.get_template(template_name)
        return mytemplate.render(**template_vars)


    def render_from_string(self, template_string, **template_vars):
        template = Template(template_string)
        return template.render(**template_vars)



    def get_page_data(self, page_size=10):
        page = int(self.get_argument("page", 1))
        offset = (page - 1) * page_size
        return page, offset, offset + (page_size - 1)


    def get_page_url(self, page):
        path = self.request.path
        query = self.request.query
        qdict = urlparse.parse_qs(query)
        for k, v in qdict.items():
            if isinstance(v, list):
                qdict[k] = v and v[0] or ''

        qdict['page'] = page
        return path + '?' + urllib.urlencode(qdict)


    def get_params(self):
        arguments = self.request.arguments
        params = {}
        for k, v in arguments.items():
            if len(v) == 1:
                params[k] = v[0]
            else:
                params[k] = v
        return params

    def get_params_obj(self, obj):
        arguments = self.request.arguments
        for k, v in arguments.items():
            if len(v) == 1:
                if type(v[0]) == str:
                    setattr(obj, k, v[0].decode('utf-8', ''))
                else:
                    setattr(obj, k, v[0])
            else:
                if type(v) == str:
                    setattr(obj, k, v.decode('utf-8'))
                else:
                    setattr(obj, k, v)
        return obj


    def get_current_user(self):
        username = self.get_secure_cookie("username")
        if not username: return None
        user = self.get_user(username)
        return user

    def get_user(self, username):
        pass
        # user = self.db.get_admin()
        # return user



class PageNotFoundHandler(BaseHandler):
    def get(self):
        raise tornado.web.HTTPError(404)

